package com.zjmzxfzhl.modules.app.controller;

import java.util.*;

import javax.validation.Valid;

import com.zjmzxfzhl.common.core.util.SecurityUtils;
import com.zjmzxfzhl.common.log.annotation.Log;
import com.zjmzxfzhl.modules.app.entity.AppDir;
import com.zjmzxfzhl.modules.app.entity.AppProj;
import com.zjmzxfzhl.modules.app.entity.AppTask;
import com.zjmzxfzhl.modules.app.form.AppDocVo;
import com.zjmzxfzhl.modules.app.form.DirCrumbVo;
import com.zjmzxfzhl.modules.app.form.TaskCrumbVo;
import com.zjmzxfzhl.modules.app.service.AppDirService;
import com.zjmzxfzhl.modules.app.service.AppProjService;
import com.zjmzxfzhl.modules.app.service.AppTaskService;
import com.zjmzxfzhl.modules.flowable.service.ProcessInstanceService;
import com.zjmzxfzhl.modules.flowable.vo.ProcessInstanceRequest;
import org.apache.xpath.operations.Bool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zjmzxfzhl.common.core.Result;
import com.zjmzxfzhl.common.core.base.BaseController;
import com.zjmzxfzhl.modules.app.entity.AppDoc;
import com.zjmzxfzhl.modules.app.service.AppDocService;

/**
 * Controller
 *
 * @author 张森荣
 */
@RestController
@RequestMapping("/app/doc")
public class AppDocController extends BaseController {
    @Autowired
    private AppDocService appDocService;
    @Autowired
    private AppDirService appDirService;
    @Autowired
    private AppProjService appProjService;
    @Autowired
    private AppTaskService appTaskService;

    /**
     * 自定义查询列表
     *
     * @param appDocVo
     * @param current
     * @param size
     * @param isMyCreate 查看我创建的文件（0:全部文件,1:我创建的文档）
     * @param isUpdate   查看最近修改的文件（0:全部文件,1:最近修改的文件）
     * @return
     */
//    @PreAuthorize("@elp.single('app:doc:list')")
    @GetMapping(value = "/list")
    public Result list(AppDocVo appDocVo, @RequestParam Integer current, @RequestParam Integer size, Integer isMyCreate, Integer isUpdate) {
        Map<String, Object> resultMap = new HashMap();
        //查询文档条件
        boolean bool = true;//是否查询目录

        if (isMyCreate != null && isMyCreate == 1) {
            String userId = SecurityUtils.getUserId();
            if (userId == null) {
                return Result.error("找不到用户");
            }
            appDocVo.setCreateBy(userId);
            bool = false;
        }
        if (isUpdate != null && isUpdate == 1) {
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(new Date());
            calendar.add(calendar.DATE, -30);
            appDocVo.setUpdateTime(calendar.getTime());
            bool = false;
        }
        if (appDocVo.getDeleted() == null) {
            appDocVo.setDeleted("0");
        }
        //回收站不显示目录
        if ("1".equals(appDocVo.getDeleted())) {
            bool = false;
        }
        //不传类型时不反回文件
        if (appDocVo.getDocType() == null || "".equals(appDocVo.getDocType())) {
            appDocVo.setDocType("##");
        }
        //查询回收站时无需类型id
//        if ("1".equals(appDocVo.getDeleted())) {
//            appDocVo.setDocType(null);
//        }
        //查看我创建的文档
        String userId = SecurityUtils.getUserId();
        if (appDocVo.getDocTypeId() == null || "".equals(appDocVo.getDocTypeId())) {
            if (!"admin".equals(userId)) {
                if ("00".equals(appDocVo.getDocType())) {
                    appDocVo.setProjUserId(userId);
                }
                if ("01".equals(appDocVo.getDocType())) {
                    appDocVo.setTaskUserId(userId);
                }
                if ("02".equals(appDocVo.getDocType())) {
                    appDocVo.setProdUserId(userId);
                }
                if ("04".equals(appDocVo.getDocType())) {
                    appDocVo.setCreateBy(userId);
                }
            }
        } else {
            bool = false;
        }
        //找任务会议纪要是制空doc
        if (appDocVo.getTaskMeet() != null && !"".equals(appDocVo.getTaskMeet())) {
            bool = false;
        }
        //没有目录id和类型id时查询无目录文件
        if (appDocVo.getDirId() == null && appDocVo.getDocTypeId() == null && (isUpdate != null && isUpdate != 1) && (isMyCreate != null && isMyCreate != 1) && !"1".equals(appDocVo.getDeleted())) {
            appDocVo.setDirId("");
        }
        //通过项目id查看项目、项目任务文档时置空文档类型，类型id
        if (appDocVo.getProjDoc() != null || appDocVo.getProjTaskDoc() != null) {
            appDocVo.setDocType(null);
            appDocVo.setDocTypeId(null);
        }

        //查询目录条件
        List<AppDir> appDirList = new ArrayList<>();
        int dirTotal = 0;
        if (bool) {
            AppDir appDir = new AppDir();
            appDir.setName(appDocVo.getName());
            appDir.setDirType(appDocVo.getDocType());
            if ("02".equals(appDocVo.getDocType())) {
                if (appDocVo.getDocSubtype() != null) {
                    switch (appDocVo.getDocSubtype()) {
                        case "01":
                            appDir.setDirType("201");
                            appDir.setDirTypeId(appDocVo.getDocTypeId());
                            break;
                        case "02":
                            appDir.setDirType("202");
                            appDir.setDirTypeId(appDocVo.getDocTypeId());
                            break;
                        case "03":
                            appDir.setDirType("203");
                            appDir.setDirTypeId(appDocVo.getDocTypeId());
                    }
                }
            }
            //合同文档时修改目录
            if ("50".equals(appDocVo.getDocSubtype())) {
                appDir.setDirType("00");
            }
            if (appDocVo.getDirId() == null || "".equals(appDocVo.getDirId())) {
                appDir.setDirLevel("1");
            } else {
                appDir.setParentDirId(appDocVo.getDirId());
            }
            if ("04".equals(appDocVo.getDocType())) {
                if (!"admin".equals(userId)) {
                    appDir.setCreateBy(userId);
                }
            }
            //查出目录
            dirTotal = appDirService.selectRowCount(appDir);
            appDirList = appDirService.getList(new Page<AppDir>(current, size), appDir);

        }
        resultMap.put("dirData", appDirList);

        //查出文档补全
        int docTotal = appDocService.selectRowCount(appDocVo);
        int total = dirTotal + docTotal;
        resultMap.put("total", total);  //总记录数

        List<AppDocVo> appDocVoList = new ArrayList<>();

        int docCurrent = 0;//文档页数
        int docSize = 0;//文档页数大小

        if ((current * size) > dirTotal) {//当前页目录数量不够
            //所需扑的文档数
            int lack = current * size - dirTotal;
            if (appDirList.size() > 0) {//当前页存在目录
                docCurrent = 1;
                docSize = lack;
                appDocVoList = appDocService.getList(new Page<AppDocVo>(docCurrent, docSize), appDocVo);
            } else {
                //没有目录，全用文档补充，但文档可以上几页也补过了
                Integer useTotal = 0;
                if (current==1) {
                    docCurrent = current;
                } else {
                    docCurrent = current-1;
                    //注意应是上一页被用了多少
                    if (dirTotal>docCurrent*size) {
                        //上一页还有目录
                        useTotal = docCurrent * size - dirTotal;
                    } else {
                        //上一页没有目录了
                        if (current>2) {
                            useTotal = docCurrent * size - dirTotal - (current-2)*size;
                        } else {
                            useTotal = docCurrent * size - dirTotal;
                        }
                    }
                }

                //补充上一页没有的
                List<AppDocVo> appDocVos = appDocService.getList(new Page<AppDocVo>(docCurrent, size), appDocVo);
                for (int i = useTotal; i < size; i++) {
                    if (appDocVos.size()>i) {
                        appDocVoList.add(appDocVos.get(appDocVos.size() - i - 1));
                    }
                }
                if (current>1) {
                    int newNum = appDocVoList.size();
                    appDocVos = appDocService.getList(new Page<AppDocVo>(current, size), appDocVo);
                    for (int i = 0; i < size - newNum && appDocVos.size() > i; i++) {
                        appDocVoList.add(appDocVos.get(i));
                    }
                }

            }
        }

        for (AppDocVo doc : appDocVoList) {
            if (doc.getDocTypeId() != null && !"".equals(doc.getDocTypeId())) {
                if ("00".equals(doc.getDocType())) {
                    String[] idsArr = doc.getDocTypeId().split(",");
                    List<AppProj> appProjList = new ArrayList<>();
                    for (String id : idsArr) {
                        AppProj appProj = appProjService.queryById(id);
                        appProjList.add(appProj);
                    }
                    doc.setProjList(appProjList);
                }
                if ("01".equals(doc.getDocType())) {
                    String[] idsArr = doc.getDocTypeId().split(",");
                    List<AppTask> appTaskList = new ArrayList<>();
                    for (String id : idsArr) {
                        AppTask appTask = appTaskService.queryById(id);
                        appTaskList.add(appTask);
                    }
                    doc.setTaskList(appTaskList);
                }
            }
        }
        resultMap.put("docData", appDocVoList);
        //产品目录添加面包屑
        if ("02".equals(appDocVo.getDocType())) {
            if ("01".equals(appDocVo.getDocSubtype()) || "02".equals(appDocVo.getDocSubtype()) || "03".equals(appDocVo.getDocSubtype())) {
                if (appDocVo.getDirId() != null && !"".equals(appDocVo.getDirId())) {
                    List<DirCrumbVo> dirCrumbVos = appDirService.dirCrumb(appDocVo.getDirId());
                    resultMap.put("dirCrumb", dirCrumbVos);
                } else {
                    resultMap.put("dirCrumb", new ArrayList<>());
                }
            }
        }
        return Result.ok(resultMap);
    }

    //    @PreAuthorize("@elp.single('app:doc:list')")
    @GetMapping(value = "/queryById")
    public Result queryById(@RequestParam String id) {
        AppDoc appDoc = appDocService.queryById(id);
        return Result.ok(appDoc);
    }

    /**
     * @param appDoc
     * @return
     * @功能：新增
     */
//    @PreAuthorize("@elp.single('app:doc:save')")
    @PostMapping(value = "/save")
    public Result save(@Valid @RequestBody AppDoc appDoc) {
        Boolean bool = appDocService.saveAppDoc(appDoc);
        if (bool == false) {
            return Result.error("保存失败");
        }
        appDoc = appDocService.queryById(appDoc.getDocId());
        return Result.ok();
    }

    /**
     * @param appDoc
     * @return
     * @功能：修改
     */
//    @PreAuthorize("@elp.single('app:doc:update')")
    @PutMapping(value = "/update")
    public Result update(@Valid @RequestBody AppDoc appDoc) {
        appDocService.updateAppDoc(appDoc);
        return Result.ok();
    }

    /**
     * @param ids
     * @return
     * @功能：批量删除
     */
//    @PreAuthorize("@elp.single('app:doc:delete')")
    @DeleteMapping(value = "/delete")
    public Result delete(@RequestParam String ids) {
        if (ids == null || ids.trim().length() == 0) {
            return Result.error("ids can't be empty");
        }
        String[] idsArr = ids.split(",");
        if (idsArr.length > 1) {
            appDocService.removeByIds(Arrays.asList(idsArr));
        } else {
            appDocService.removeById(idsArr[0]);
        }
        return Result.ok();
    }

    /**
     * @param ids
     * @return
     * @功能：软删除
     */
//    @PreAuthorize("@elp.single('app:doc:delete')")
    @DeleteMapping(value = "/softDelete")
    public Result softDelete(@RequestParam String ids) {
        if (ids == null || ids.trim().length() == 0) {
            return Result.error("ids can't be empty");
        }
        Boolean result = appDocService.softDelete(ids);
        if (result == false) {
            return Result.error("删除失败");
        }
        return Result.ok();
    }

    /**
     * @param ids
     * @param dirId
     * @return
     * @功能：恢复
     */
//    @PreAuthorize("@elp.single('app:doc:delete')")
    @GetMapping(value = "/recovery")
    public Result recovery(@RequestParam String ids, @RequestParam String dirId) {
        if (ids == null || ids.trim().length() == 0) {
            return Result.error("ids can't be empty");
        }
        Boolean result = appDocService.recovery(ids, dirId);
        if (result == false) {
            return Result.error("删除失败");
        }
        return Result.ok();
    }

    /**
     * @param docId
     * @param status
     * @return
     * @功能： 任务变更{00.已上传,01.待审批,02.审批中,04.审批过,05.已驳回,06.已过期,07.已作废}
     */
//    @PreAuthorize("@elp.single('app:Doc:update')")
    @PutMapping(value = "/docChange")
    public Result docChange(@RequestParam String docId, @RequestParam String status) {
        Boolean result = true;
        switch (status) {
            case "00": //已上传
                result = appDocService.uploaded(docId);
                break;
            case "01": //待审批
                result = appDocService.pendingTrial(docId);
                break;
            case "02": //审批中
                result = appDocService.inReview(docId);
                break;
            case "04": //审批过
                result = appDocService.reviewed(docId);
                break;
            case "05": //已驳回
                result = appDocService.reject(docId);
                break;
            case "06": //已过期
                result = appDocService.timeout(docId);
                break;
            case "07": //已作废
                result = appDocService.cancel(docId);
                break;
            default:
                return Result.error("查找文档状态失败！");
        }
        if (result == false) {
            return Result.error("文档状态更改失败！");
        }
        return Result.ok();
    }

    @Log(value = "启动文档审批流程实例")
    @PostMapping(value = "/processStart")
    @Transactional(rollbackFor = Exception.class)
    public Result processStart(@RequestParam String docId) {
        Boolean result = appDocService.processStart(docId);
        return Result.ok();
    }

    @GetMapping(value = "/procDoc")
    public Result procDoc(@RequestParam String processInstanceId) {
        List<AppDocVo> appDocVoList = appDocService.procDoc(processInstanceId);
        AppDocVo result = null;
        if (appDocVoList.size() > 0) {
            result = appDocVoList.get(0);
        }
        return Result.ok(result);
    }

    @Log(value = "查询子任务文档")
    @GetMapping(value = "/subTaskDoc")
    public Result subTaskDoc(@RequestParam String taskId) {
        List<AppDocVo> result = appDocService.subTaskDoc(taskId);
        return Result.ok(result);
    }
}
